/* 建造者模式 */

pub struct User {
    pub name: String,
    age: u8,
    sex: Sex
}

impl User {

    pub fn builder() -> UserBuilder{
        UserBuilder {
            name: String::from(""),
            age: 0,
            sex: Sex::Male
        }
    }
}

pub enum Sex {
    Male,
    Female
}

pub struct UserBuilder {
    name: String,
    age: u8,
    sex: Sex
}

impl UserBuilder {
    pub fn name(mut self, name: &str) -> UserBuilder {
        self.name = String::from(name);
        self
    }

    pub fn age(mut self, age: u8) -> UserBuilder {
        self.age = age;
        self
    }

    pub fn sex(mut self, sex: Sex) -> UserBuilder {
        self.sex = sex;
        self
    }

    pub fn build(self) -> User {
        User {
            name: self.name,
            age: self.age,
            sex: self.sex
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use std::matches;

    #[test]
    fn test_builder_1() {
        let builder = User::builder();
        let user = builder.name("张三")
            .age(25).sex(Sex::Female).build();
        
        assert_eq!(String::from("张三"), user.name);
        assert_eq!(25, user.age);
        assert!(matches!(user.sex, Sex::Female ));
    }
}